﻿using Core.Entities;
using Core.ReadWriter;
using Core.Reader;
using Core.Tools;
using Core.Writer;
using System;
using System.Collections.Generic;
using Core.Enums;

namespace Core.CommandProcesser
{
    public class SystemProcesser : BaseCommandProcesser
    {
        /// <summary> 储存系统命令实现 </summary>
        private readonly Dictionary<string, ISystemCommand> SystemCommands;

        public SystemProcesser(params string[] CommandAssemblyNames)
        {
            SystemCommands = new Dictionary<string, ISystemCommand>();

            foreach (var AssemblyName in CommandAssemblyNames)
            {
                var AssemblyItem = AppDomain.CurrentDomain.Load(AssemblyName);

                foreach (var TypeItem in AssemblyItem.GetTypes())
                {
                    if (typeof(ISystemCommand).IsAssignableFrom(TypeItem) && !TypeItem.IsInterface && !TypeItem.IsAbstract)
                    {
                        var ItemInstance = (ISystemCommand)TypeItem.GetConstructor(Type.EmptyTypes).Invoke(null);

                        if (ItemInstance.Name == null || ItemInstance.Name.Length == 0)
                        {
                            throw new Exception("注册系统命令处理程序时 -- Name -- 属性是必须的");
                        }

                        if (SystemCommands.ContainsKey(ItemInstance.Name))
                        {
                            throw new Exception("命令处理程序 -- " + ItemInstance.Name + " -- 已经注册过了");
                        }

                        SystemCommands.Add(ItemInstance.Name, ItemInstance);
                    }
                }
            }
        }

        public override void Process(BaseProcess Process, CommandInfo CommandInfo, Action<IDataReader> Callback)
        {
            var CSharpCommand = CommandInfo.InternalTag as ISystemCommand;

            if (CSharpCommand == null)
            {
                throw new Exception(CommandInfo.Name + " -- 该命令没有实现！");
            }

            var TableContent = new Table();

            TableContent.Next();

            using (var ReadWriter = new TableReadWriter(TableContent))
            {
                if ((CommandInfo.Sign & CommandSigns.SingleObjectResult) != 0)
                {
                    ReadWriter.ObjectType = RWTypes.Object;
                }
                else
                {
                    ReadWriter.ObjectType = RWTypes.Table;
                }

                CSharpCommand.Process(Process, CommandInfo, ReadWriter);

                Callback(ReadWriter);
            }
        }
        
        public override void Process(BaseProcess Process, CommandInfo CommandInfo, IDataWriter Writer)
        {
            var CSharpCommand = CommandInfo.InternalTag as ISystemCommand;

            if (CSharpCommand == null)
            {
                throw new Exception(CommandInfo.Name + " -- 该命令没有实现！");
            }

            Writer.Next();

            CSharpCommand.Process(Process, CommandInfo, Writer);
        }

        public override void Initialization(CommandInfo CommandInfo)
        {
            string TempCode = CommandInfo.Code;
            
            var ValidationsList = new List<CommandFieldVerifier>();

            GetValidations(ref TempCode, null, null, ValidationsList);

            CommandInfo.InternalValidations = ValidationsList.ToArray();

            ISystemCommand SystemCommand;

            if (!SystemCommands.TryGetValue(CommandInfo.Name, out SystemCommand))
            {
                throw new Exception("程序没有实现该命令 -- " + CommandInfo.Name + " -- 请联系开发人员");
            }

            CommandInfo.InternalTag = SystemCommand;
        }
    }
}